chrome.runtime.onMessage.addListener(
    function (data) {
        const SCROLL_DELTA = 500
        let foundAbtCodes = new Set()

        function execFunc(func, ...params) {
            typeof func === 'function' && func(...params)
        }

        function getContainer() {
            return document.querySelector('.ag-body-viewport')
        }

        function getIfBindContainerScroll() {
            const container = getContainer()
            return container.getAttribute('data-bind-scroll-event')
        }

        function bindContainerScroll(onScroll) {
            if (!getIfBindContainerScroll()) {
                const container = getContainer()
                container.addEventListener('scroll', onScroll)
                container.setAttribute('data-bind-scroll-event', '1')
            }
        }

        function setElBackgroundColor(el, color) {
            el.style.backgroundColor = color
        }

        function setElTitle(el, title) {
            el.setAttribute('title', title)

            let label = el.querySelector('.abt_ratio_label')
            if (!label) {
                label = document.createElement('div')
                label.setAttribute('style', 'position: absolute;left:0;top:0;border: solid 1px red;background: yellow;')
                el.appendChild(label)
            }

            label.innerText = title
        }

        function displayRatioOfCurrentPage() {
            const rows = getAllRows()

            for (let i = 0; i < rows.length; i++) {
                const row = rows[i]
                const abtCode = getAbtCodeOfRow(row)

                // 如果当前开关配置了abt
                if (abtCode) {
                    const abtRatio = window.__ratioWrapper__[abtCode]

                    // 如果搜索结果中不存在这个配置，说明这个ab没有上线或者已经下线，需要红色告警提示
                    if (!abtRatio) {
                        setElBackgroundColor(row, '#f1b1b1')
                        setElTitle(row, `实验号${abtCode}不存在，未上线或已下线，请及时删掉该实验号`)
                    } else {
                        // 如果存在，再看是否其中某个版本为100%流量，是的话也要警告
                        const allVersions = Object.keys(abtRatio)
                        setElTitle(row, allVersions.reduce((prev, next) => { prev.push(`${next}:${abtRatio[next]}`); return prev; }, [`实验号${abtCode}流量：`]).filter(Boolean).join(' '))
                        const fullRatioVersion = allVersions.find(version => abtRatio[version] === '100%')
                        if (fullRatioVersion) {
                            setElBackgroundColor(row, fullRatioVersion === 'A' ? '#f1d6a6' : '#b4e2b4')
                        } else {
                            setElBackgroundColor(row, '#b7ddfd')
                        }
                    }
                }
            }
        }

        function showRatioResult(ratioWrapper) {
            window.__ratioWrapper__ = ratioWrapper
            displayRatioOfCurrentPage()

            bindContainerScroll(() => {
                setTimeout(() => {
                    displayRatioOfCurrentPage()
                }, 50)
            })
        }

        function getContainerHeight() {
            const container = getContainer()
            return container.scrollHeight
        }

        function getCurrentScrollTop() {
            return getContainer().scrollTop
        }

        function getIfCanScrollNext() {
            const currentScrollTop = getCurrentScrollTop()
            const totalHeight = getContainerHeight()

            return currentScrollTop < (totalHeight - SCROLL_DELTA)
        }

        function scrollNext() {
            getContainer().scrollTo(0, getCurrentScrollTop() + SCROLL_DELTA)
        }

        function getIfExistContainer() {
            return !!getContainer()
        }

        function resetScroll(onFinishResetScroll) {
            getContainer().scrollTo(0, 0)
            setTimeout(() => {
                execFunc(onFinishResetScroll)
            }, 100)
        }

        function startScroll(onFinishCurrentScroll, onFinishAllScroll) {
            execFunc(onFinishCurrentScroll)
            const canScroll = getIfCanScrollNext()

            if (canScroll) {
                scrollNext()
                setTimeout(() => {
                    startScroll(onFinishCurrentScroll, onFinishAllScroll)
                }, 100)
            } else {
                execFunc(onFinishAllScroll)
            }
        }

        function getAbtCodeOfRow(row) {
            try {
                return row.querySelector('div:nth-child(9)>div>span').textContent
            } catch (error) {
                return ''
            }
        }

        function getAllRows() {
            return Array
                .from(document.querySelectorAll('.ag-body-viewport .ag-body-container [role="row"]'))
        }

        function onFindAbt() {
            if (getIfExistContainer()) {
                resetScroll(() => {
                    foundAbtCodes = new Set()
                    startScroll(() => {
                        const rows = getAllRows()

                        if (rows.length) {
                            const currentAbtCodes = rows
                                .map(row => getAbtCodeOfRow(row))
                                .filter(Boolean)

                            currentAbtCodes.forEach(code => foundAbtCodes.add(code))
                        }
                    }, () => {
                        resetScroll()
                        chrome.runtime.sendMessage({
                            action: 'abt_result',
                            payload: Array.from(foundAbtCodes)
                        })
                    })
                })
            }
        }

        let { action, payload } = data
        switch (action) {
            case 'find_abt':
                onFindAbt()
                break
            case 'display_abt_ratio':
                showRatioResult(payload)
                break
            default:
                break
        }
    }
)